package cn.com.lms.business.core.util;

import cn.com.lms.business.course.service.FbCourseInfoService;
import cn.com.lms.business.livecourse.service.AliVodService;
import cn.com.lms.business.livecourse.service.CourseLiveService;
import cn.com.lms.config.ALiYunKeyConfig;
import cn.com.lms.config.DfsResConfig;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.vod.upload.impl.UploadVideoImpl;
import com.aliyun.vod.upload.req.UploadStreamRequest;
import com.aliyun.vod.upload.resp.UploadStreamResponse;
import com.bnzj.core.rest.ResponseResult;
import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.exception.FdfsUnsupportStorePathException;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.UUID;

/*
 * @author liuwei
 * @date 2020/3/17 10:39
 * @desc FDFS文件上传工具类
 */
@Component
public class FastDfsUtils {

    @Autowired
    private FastFileStorageClient storageClient;

    @Autowired
    private DfsResConfig dfsResConfig;

    @Autowired
    private AliVodService aliVodService;


    /**
     * 下载文件
     *
     * @param fileUrl 文件url
     * @return
     */
//    public byte[] download(String fileUrl) {
//        StorePath storePath = StorePath.praseFromUrl(fileUrl);
//        byte[] data = storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadByteArray());
//        return data;
//    }

    /**
     * 下载文件
     * @param fileUrl 文件url
     * @return
     */
    public byte[] download(String fileUrl) {
        String endpoint = ALiYunKeyConfig.END_POINT;
        String accessKeyId = ALiYunKeyConfig.ACCESS_KEY_ID;
        String accessKeySecret = ALiYunKeyConfig.ACCESS_KEY_SECRET;
        String bucketName = ALiYunKeyConfig.BUCKET_NAME;
        try {
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

            // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
            OSSObject ossObject = ossClient.getObject(bucketName, fileUrl);
            InputStream in = ossObject.getObjectContent();
            byte[] bytes = toByteArray(in);
            in.close();
            // 关闭OSSClient。
            ossClient.shutdown();
            return bytes;
        }catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * io流转化为byte数组方法
     * */
    private byte[] toByteArray(InputStream in) throws IOException {

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024 * 4];
        int n = 0;
        while ((n = in.read(buffer)) != -1) {
            out.write(buffer, 0, n);
        }
        return out.toByteArray();
    }

    /**
     * @return
     * @Author liuwei
     * @Description MultipartFile类型的文件上传ַ
     * @Date 2020-03-17
     * @Param [file]
     */
//    public ResponseResult<String> uploadFile(MultipartFile file) {
//        try {
//            StorePath path = storageClient.uploadFile(file.getInputStream(), file.getSize(),
//                    FilenameUtils.getExtension(file.getOriginalFilename()), null);
//
//            return ResponseResult.success(getResAccessUrl(path));
//        } catch (Exception e) {
//            e.printStackTrace();
//            return ResponseResult.failure(0, "上传失败");
//        }
//
//    }

    /**
     * @return
     * @Author lixin
     * @Description MultipartFile类型的文件上传ַ
     * @Date 2020-05-25
     * @Param [file]
     */
    public ResponseResult<String> uploadFile(MultipartFile file) {
        try {
            // 创建OSS实例
            OSS ossClient = new OSSClientBuilder().build(ALiYunKeyConfig.END_POINT, ALiYunKeyConfig.ACCESS_KEY_ID, ALiYunKeyConfig.ACCESS_KEY_SECRET);
            // 获取上传文件输入流
            InputStream inputStream = file.getInputStream();
            // 获取随机唯一值
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            // 获取文件名称
            String filename = file.getOriginalFilename();
            // 把文件按照日期进行分类
            String datePath = new DateTime().toString("yyyy/MM/dd");
            // 拼接字符串
            filename = datePath + "/" + uuid + filename;
            // 使用oss方法实现上传
            ossClient.putObject(ALiYunKeyConfig.BUCKET_NAME, filename, inputStream);
            // 关闭OssClient
            ossClient.shutdown();
            String url = "https://" + ALiYunKeyConfig.BUCKET_NAME + "." + ALiYunKeyConfig.END_POINT + "/" + filename;
            return ResponseResult.success(url);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.failure(0, "上传失败");
        }
    }

    public ResponseResult<FileInfoVO> uploadFileBase64(MultipartFile file) {

        String suffFix = getFileSuffFix(file.getOriginalFilename());
        FileInfoVO fileInfoVO = new FileInfoVO();
        try {
            StorePath path = storageClient.uploadFile(file.getInputStream(), file.getSize(),
                    FilenameUtils.getExtension(file.getOriginalFilename()), null);
            fileInfoVO.setFilePath(getResAccessUrl(path));
            InputStream in = file.getInputStream();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            byte[] buff = new byte[1024];
            int rc;
            while ((rc = in.read(buff)) != -1) {
                out.write(buff, 0, rc);
            }
            byte[] fileByte = out.toByteArray();
            fileInfoVO.setFileByte(fileByte);
            String type = "data:image/" + suffFix + ";base64,";
            String strFile = Base64.encodeBase64String(fileByte);
            fileInfoVO.setBase64FilePath(type + strFile);
            return ResponseResult.success(fileInfoVO);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.failure(0, fileInfoVO);
        }
    }

    public String getFileSuffFix(String fileUrl) {
        if (fileUrl.lastIndexOf(".") < 0) {
            return null;
        }
        String suffix = fileUrl.substring(fileUrl.lastIndexOf(".") + 1);
        return suffix;
    }


    /**
     * @return
     * @Author liuwei
     * @Description 普通的文件上传
     * @Date 2020-03-17
     * @Param [file]
     */
    public ResponseResult<String> uploadFile(File file) {

        try {
            FileInputStream inputStream = new FileInputStream(file);
            StorePath path = storageClient.uploadFile(inputStream, file.length(),
                    FilenameUtils.getExtension(file.getName()), null);
            return ResponseResult.success(path.getFullPath());
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.failure(0, "上传失败");
        }
    }

    /**
     * @return
     * @Author liuwei
     * @Description 带输入流形式的文件上传
     * @Date 2020-03-17
     * @Param [is, size, fileName]
     */
    public ResponseResult<String> uploadFileStream(InputStream is, long size, String fileName) {
        StorePath path = storageClient.uploadFile(is, size, fileName, null);
        return ResponseResult.success(path.getFullPath());
    }


    /**
     * @return
     * @Author liuwei
     * @Description 删除文件
     * @Date 2020-03-17
     * @Param [fileUrl]
     */
    public ResponseResult deleteFile(String fileUrl) {

        if (StringUtils.isEmpty(fileUrl)) {
            return ResponseResult.failure(0, "");
        }
        try {
            StorePath storePath = StorePath.praseFromUrl(fileUrl);
            storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
            return ResponseResult.success();
        } catch (FdfsUnsupportStorePathException e) {
            e.printStackTrace();
            return ResponseResult.failure(0, "上传失败");
        }
    }

    /**
     * 封装文件完整URL地址
     *
     * @param storePath
     * @return
     */
    private String getResAccessUrl(StorePath storePath) {
        return "/" + storePath.getFullPath();
    }

    /**
     * @return 阿里云OSS的图片url
     * @Author lixin
     * @Description MultipartFile类型的文件上传ַ
     * @Date 2020-05-09
     * @Param [file]
     */
    public ResponseResult<String> uploadFileAvatar(MultipartFile file) {
        // 工具类获取值
        String endpoint = ALiYunKeyConfig.END_POINT;
        String accessKeyId = ALiYunKeyConfig.ACCESS_KEY_ID;
        String accessKeySecret = ALiYunKeyConfig.ACCESS_KEY_SECRET;
        String bucketName = ALiYunKeyConfig.BUCKET_NAME;

        try {
            // 创建OSS实例
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            // 获取上传文件输入流
            InputStream inputStream = file.getInputStream();
            // 获取随机唯一值
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            // 获取文件名称
            String filename = file.getOriginalFilename();
            // 把文件按照日期进行分类
            String datePath = new DateTime().toString("yyyy/MM/dd");
            // 拼接字符串
            filename = datePath + "/" + uuid + filename;
            // 使用oss方法实现上传
            ossClient.putObject(bucketName, filename, inputStream);
            // 关闭OssClient
            ossClient.shutdown();
            String url = "https://" + bucketName + "." + endpoint + "/" + filename;
            return ResponseResult.success(url);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * @return 阿里云OSS的视频id
     * @Author lixin
     * @Description MultipartFile类型的文件上传ַ
     * @Date 2020-05-09
     * @Param [file]
     */
    public ResponseResult<String> uploadALiYunFile(MultipartFile file) {
        try {
            String fileName = file.getOriginalFilename();
            assert fileName != null;
            String title = fileName.substring(0, fileName.lastIndexOf("."));
            InputStream in = file.getInputStream();
            UploadStreamRequest request = new UploadStreamRequest(AliVodService.ACCESS_KEY_ID,
                    AliVodService.ACCESS_KEY_SECRET, title, fileName, in);
            request.setPrintProgress(true);
            request.setInputStream(in);
            UploadVideoImpl uploadVideo = new UploadVideoImpl();
            UploadStreamResponse response = uploadVideo.uploadStream(request);
            String videoId = null;
            String playUrl = null;
            Long courseInfoId = null;
            if (response.isSuccess()) {
                videoId = response.getVideoId();
                playUrl = aliVodService.vodPlayUrl(videoId);



            }else {
                String message = response.getMessage();
                return ResponseResult.failure(0, message);
            }
            return ResponseResult.success(playUrl);
        }catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.failure(0, "上传失败");
        }
    }
}
